package FlowGram.Application.IDEWindow;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;

import net.miginfocom.swing.MigLayout;

import FlowGram.Application.Application;
import FlowGram.Application.CommandHost.CommandHost;
import FlowGram.Application.IDEWindow.FileHost.FileHost;
//import FlowGram.Application.IDEWindow.MockFilehost.FileHost;
import FlowGram.Application.IDEWindow.FileManager.FileManager;
import FlowGram.Application.Parser.FinchParserException;
import FlowGram.Application.Parser.FinchProgramFlow;
import FlowGram.Application.SimulatorWindow.SimulationWindow;


/**
 * 
 * @author thackray
 *
 */
public class MainWindow extends JFrame implements ActionListener, ComponentListener {
	
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	
	private JMenuBar menuBar;
	private FileManager fileman;
	private FileHost filehost;
	private CommandHost cmdHost;
	
	
	
	public MainWindow(){
		this.setTitle("FlowGram .::. IDE");
		
		this.setSize(600, 600);
		Container content = this.getContentPane();
	    content.setBackground(Color.white);
	    content.setLayout(new BorderLayout());
		
		GridBagConstraints gbc = new GridBagConstraints();
		
		this.addWindowListener(new WindowAdapter()
	      {
	         public void windowClosing(WindowEvent e)
	         {
	        	 Application.getInstance().exit();
	         }
	      });

		
		
		this.fileman = new FileManager();
		this.fileman.setSize(250, 600);
		this.fileman.setPreferredSize(new Dimension(250, 600));
		
		this.filehost = new FileHost();
		this.filehost.setSize(500, this.getHeight());
		this.filehost.setPreferredSize(new Dimension(500, 800));
		this.filehost.setBorder(BorderFactory.createLineBorder(new Color(0,0,0)));
		
		
		this.cmdHost = new CommandHost();
		this.cmdHost.setMinimumSize(new Dimension(200, 600));
		this.cmdHost.setSize(200, 600);
		this.cmdHost.setPreferredSize(new Dimension(200, 600));
		
		
		this.createMenu();
		content.add(this.menuBar, BorderLayout.PAGE_START);
		
		JSplitPane fmanSplit = new JSplitPane();
		fmanSplit.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
		
		JSplitPane cmdHstSplit = new JSplitPane();
		cmdHstSplit.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
		
		//cmdHstSplit.setLeftComponent(this.filehost);
		//cmdHstSplit.setRightComponent(this.cmdHost);
		
		fmanSplit.setLeftComponent(this.fileman);
		fmanSplit.setRightComponent(this.filehost);
		
		content.add(fmanSplit);
		
		/*content.add(this.fileman, BorderLayout.LINE_START);
		content.add(this.filehost, BorderLayout.CENTER);*/
		content.add(this.cmdHost, BorderLayout.LINE_END);
		
		this.addComponentListener(this);
		
		this.validate();
		this.pack();
	}
	public FileHost getFileHost(){
		return this.filehost;
	}
	public String getCurrentProject(){
		return this.fileman.getCurrentProjectPath();
	}
	public void refreshFileManager(){
		this.fileman.refresh();
	}
	protected void createMenu(){
		this.menuBar = new JMenuBar();
		
		JMenu fileMenu = new JMenu("File");
		fileMenu.setMnemonic(KeyEvent.VK_F);
		
		JMenu newMenuItem = new JMenu("New");
		newMenuItem.setIcon(Application.loadIcon("general/New16.gif"));
		newMenuItem.setMnemonic(KeyEvent.VK_N);
		
		JMenuItem newProjectMenuItem = new JMenuItem("Project");
		newProjectMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
				MainWindow.this.fileman.newProject();
            }
        });
		newMenuItem.add(newProjectMenuItem);
		newMenuItem.addSeparator();
		JMenuItem newCodeFileMenuItem = new JMenuItem("Code File");
		newCodeFileMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                try {
					MainWindow.this.filehost.newFile();
				} catch (FinchParserException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        });
		newMenuItem.add(newCodeFileMenuItem);
		JMenuItem newTerrainFileMenuItem = new JMenuItem("Terrain File");
		newTerrainFileMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
				MainWindow.this.fileman.newFile(MainWindow.this.fileman.getCurrentProjectTerrainsPath(), "terr");
            }
        });
		newMenuItem.add(newTerrainFileMenuItem);
		fileMenu.add(newMenuItem);
		
		JMenuItem openFileMenuItem = new JMenuItem("Open...");
		openFileMenuItem.setIcon(Application.loadIcon("general/Open16.gif"));
		openFileMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	JFileChooser chooser = new JFileChooser();
            	chooser.setSelectedFile(new File(MainWindow.this.getCurrentProject()));
                int returnVal = chooser.showOpenDialog(null);
                if(returnVal == JFileChooser.APPROVE_OPTION) {
                	try {
                		MainWindow.this.filehost.openFile(chooser.getSelectedFile().getPath());
                	}catch(Exception e){
                		e.printStackTrace();
                	}
                }
            }
        });
		fileMenu.add(openFileMenuItem);
		
		
		fileMenu.addSeparator();
		
		JMenuItem saveMenuItem = new JMenuItem("Save", KeyEvent.VK_S);
		saveMenuItem.setIcon(Application.loadIcon("general/Save16.gif"));
		saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
		saveMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	try {
					MainWindow.this.filehost.saveFile();
					MainWindow.this.fileman.refresh();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        });
		fileMenu.add(saveMenuItem);
		
		JMenuItem saveAsMenuItem = new JMenuItem("Save As..."/*, KeyEvent.VK_S*/);
		//newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Act));
		saveAsMenuItem.setIcon(Application.loadIcon("general/SaveAs16.gif"));
		saveAsMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                JFileChooser chooser = new JFileChooser();
                if(MainWindow.this.filehost.getCurrentCodeFile().getPath() != null){
                	chooser.setSelectedFile(new File(MainWindow.this.filehost.getCurrentCodeFile().getPath()));
                }else{
                	chooser.setSelectedFile(new File(MainWindow.this.getCurrentProject()));
                }
                int returnVal = chooser.showSaveDialog(null);
                if(returnVal == JFileChooser.APPROVE_OPTION) {
                	try {
                		//JOptionPane.showMessageDialog(null, "Saving code file:\n"+chooser.getSelectedFile().getPath());
    					MainWindow.this.filehost.saveFileAs(chooser.getSelectedFile().getPath());
    					MainWindow.this.fileman.refresh();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
                }	
            }
        });
		fileMenu.add(saveAsMenuItem);
		
		JMenuItem saveAllMenuItem = new JMenuItem("Save All"/*, KeyEvent.VK_S*/);
		//newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Act));
		saveAllMenuItem.setIcon(Application.loadIcon("general/SaveAll16.gif"));
		saveAllMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	try {
	                MainWindow.this.filehost.saveAll();
	    			MainWindow.this.fileman.refresh();
            	} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        });
		fileMenu.add(saveAllMenuItem);
		
		fileMenu.addSeparator();
		
		JMenuItem closeMenuItem = new JMenuItem("Close"/*, KeyEvent.VK_S*/);
		//newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Act));
		closeMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                try {
					MainWindow.this.filehost.closeFile();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        });
		fileMenu.add(closeMenuItem);
		
		JMenuItem closeAllMenuItem = new JMenuItem("Close All"/*, KeyEvent.VK_S*/);
		//newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Act));
		closeAllMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                try {
					MainWindow.this.filehost.closeAll();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        });
		fileMenu.add(closeAllMenuItem);
		
		fileMenu.addSeparator();
		
		JMenuItem exitMenuItem = new JMenuItem("Exit");
		exitMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                Application.getInstance().exit();
            }
        });
		fileMenu.add(exitMenuItem);
		
		this.menuBar.add(fileMenu);
		
		JMenu editMenu = new JMenu("Edit");
		editMenu.setMnemonic(KeyEvent.VK_E);
		JCheckBoxMenuItem allowEditingMenuItem = new JCheckBoxMenuItem("Allow Editor Typing");
		allowEditingMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
            	if(MainWindow.this.filehost.getEditable()){
            		MainWindow.this.filehost.isNotEditable();
            		((JCheckBoxMenuItem) event.getSource()).setState(false);
            	}else{
            		MainWindow.this.filehost.isEditable();
            		((JCheckBoxMenuItem) event.getSource()).setState(true);
            	}
            }
        });
		allowEditingMenuItem.setState(this.filehost.getEditable());
		editMenu.add(allowEditingMenuItem);
		this.menuBar.add(editMenu);
		
		JMenu runMenu = new JMenu("Run");
		editMenu.setMnemonic(KeyEvent.VK_R);
		JMenuItem runProgramMenuItem = new JMenuItem("Run Program");
		runProgramMenuItem.setIcon(Application.loadIcon("media/Play16.gif"));
		runProgramMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                SimulationWindow simwin = Application.getInstance().getSimulationWindow();
                FinchProgramFlow current = MainWindow.this.filehost.getCurrentCodeFile().getProgramFlow(); 
                simwin.set_simulation(current);
                simwin.setVisible(true);
            }
        });
		runMenu.add(runProgramMenuItem);
		runMenu.addSeparator();
		JCheckBoxMenuItem connectFinchProgramMenuItem = new JCheckBoxMenuItem("Connect To Finch");
		connectFinchProgramMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
               Application app = Application.getInstance();
               if(((JCheckBoxMenuItem) event.getSource()).getState()){
	               int result = JOptionPane.showConfirmDialog(MainWindow.this, "Please ensure the Finch is connected, then press OK to connect", "Connect to Finch", JOptionPane.OK_CANCEL_OPTION);
	               if(result == JOptionPane.OK_OPTION){
	            	   boolean connectResult = app.connectFinch();
	            	   if(!connectResult){
	            		   JOptionPane.showMessageDialog(MainWindow.this, "There was an error connecting to the Finch", "Finch Connection Error", JOptionPane.ERROR_MESSAGE);
	            		   ((JCheckBoxMenuItem) event.getSource()).setState(false);
	            	   }
	               }else{
	            	   ((JCheckBoxMenuItem) event.getSource()).setState(false);
	               }
               }else{
            	   app.disconnectFinch();
               }
            }
        });
		runMenu.add(connectFinchProgramMenuItem);
		this.menuBar.add(runMenu);
		
		JMenu viewMenu = new JMenu("View");
		viewMenu.setMnemonic(KeyEvent.VK_V);
		JMenuItem simMenuItem = new JMenuItem("Simulator");
		simMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                Application.getInstance().showSimulationWindow();
            }
        });
		viewMenu.add(simMenuItem);
		
		JMenuItem ideMenuItem = new JMenuItem("IDE");
		ideMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                Application.getInstance().showIDEWindow();
            }
        });
		viewMenu.add(ideMenuItem);
		viewMenu.addSeparator();
		JMenuItem refreshWorkspaceMenuItem = new JMenuItem("Refresh Workspace");
		refreshWorkspaceMenuItem.setIcon(Application.loadIcon("general/Refresh16.gif"));
		refreshWorkspaceMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                MainWindow.this.fileman.refresh();
            }
        });
		viewMenu.add(refreshWorkspaceMenuItem);
		this.menuBar.add(viewMenu);
		
		
		JMenu helpMenu = new JMenu("Help");
		helpMenu.setMnemonic(KeyEvent.VK_H);
		JMenuItem aboutMenuItem = new JMenuItem("About");
		aboutMenuItem.setIcon(Application.loadIcon("general/About16.gif"));
		aboutMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                new AboutDialog(MainWindow.this);
            }
        });
		helpMenu.add(aboutMenuItem);
		this.menuBar.add(helpMenu);
		
	}
	public void shutdown(){
		try {
			this.filehost.closeAll();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void componentResized(ComponentEvent e) {
		this.fileman.setPreferredSize(new Dimension(this.fileman.getWidth(), this.getHeight()));
		this.filehost.setPreferredSize(this.getSize());
		this.filehost.setMinimumSize(this.getSize());
		this.validate();
		/*this.pack();*/
	}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void componentHidden(ComponentEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void componentMoved(ComponentEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void componentShown(ComponentEvent e) {
		// TODO Auto-generated method stub
		
	}
	
}
